package net.sf.rose.file.util.resource;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import net.sf.rose.util.RoseRuntimeException;

/** 
 * @author fengjian E-mail: 9110530@qq.com 
 * @version 创建时间：2015年9月25日 下午4:37:57 
 * 类说明 ：代替JDK自带的配置文件加载器
 * 特别地：
 * 1、支持配置文件参数的修改和保存
 * 2、参数列表是有顺序结构的
 */
public class ResourceIniFile_bak {

	private static Logger LOG = Logger.getLogger(ResourceIniFile_bak.class);

	/** 配置文件参数是否被更新标志 */
	private boolean updateFlag = false;

	/** 配置文件对象 */
	private File file = null;

	/**
	 * 配置文件全文内容 
	 * 其中参数只存参数名称，注释存储全文
	 */
	private List<String> content = new ArrayList<>();

	/** 所有参数的键值对 */
	private Map<String, String> paramemters = new LinkedHashMap<>();

	/** 父配置文件类 */
	private ResourceIniFile_bak parent = null;

	/**
	 * 设置文件对象
	 * @param file 文件对象
	 */
	public void setFile(File file) {
		this.file = file;
	}

	/**
	 * 获取文件对象
	 * @return 文件对象
	 */
	public File getFile() {
		return file;
	}

	/**
	 * 将所有数据读入内存
	 * @param file 文件对象
	 */
	public void load(File file) {
		this.file = file;
		if (!file.exists()) {
			LOG.warn(file.toString() + "文件不存在！");
			return;
		}
		try {
			BufferedReader reader = new BufferedReader(new FileReader(file));
			String tempString, key, val = null;
			// 不知道为什么，第一行的第一个字母是空格
			//tempString = reader.readLine();
			//content.add(tempString);
			// 一次读入一行，直到读入null为文件结束
			while ((tempString = reader.readLine()) != null) {
				if (tempString.length() == 0) {
					content.add(tempString);
				}
				else if (tempString.charAt(0) == '#') {
					content.add(tempString);
					// System.out.println(tempString);
				} else {
					tempString = tempString.trim();
					int i = tempString.indexOf('=');
					if (i == -1) {
						content.add(tempString);
					} else {
						key = tempString.substring(0, i).trim();
						val = tempString.substring(i + 1, tempString.length()).trim();
						content.add(key);
						paramemters.put(key, val);
						// System.out.println(key + '=' + val);
					}
				}
			}
			reader.close();
			LOG.warn("成功读取配置文件：" + file.getAbsolutePath());
		} catch (FileNotFoundException e) {
			String mess = "在指定的路径下没有找到配置文件：" + file.getAbsolutePath();
			LOG.error(mess, e);
			throw new RoseRuntimeException(mess, e);
		} catch (IOException e) {
			String mess = "读取配置文件：" + file.getAbsolutePath() + "时发生错误！";
			LOG.error(mess, e);
			throw new RoseRuntimeException(mess, e);
		}
	}

	/**
	 * 保存
	 * @return 是否成功
	 */
	public boolean save() {
		if (!updateFlag) {
			return false;
		}
		try {
			BufferedWriter buf = new BufferedWriter(new FileWriter(file));
			for (String key : content) {
				if (key.charAt(0) == '#') {
					buf.write(key);
				} else {
					buf.write(key + '=' + paramemters.get(key));
				}
				buf.newLine();
			}
			buf.flush();
			buf.close();
			return true;
		} catch (IOException e) {
			String mess = "保存配置文件：" + file.getAbsolutePath() + "时发生错误！";
			LOG.error(mess, e);
			return false;
		}
	}

	/**
	 * 设置父配置文件类
	 * @param parent 父配置文件实体
	 */
	public void setParent(ResourceIniFile_bak parent) {
		this.parent = parent;
	}

	/**
	 * 返回父配置文件类
	 * @return 父配置文件实体
	 */
	public ResourceIniFile_bak getParent() {
		return parent;
	}

	/**
	 * 添加注释
	 * @param comment 注释
	 */
	public void addComment(String comment) {
		content.add('#' + comment);
	}

	/**
	 * 设置属性
	 * @param key 键名
	 * @param value 键值
	 */
	public void add(String key, String value) {
		this.add(null, key, value);
	}

	/**
	 * 设置属性
	 * @param comment 注释
	 * @param key 键名
	 * @param value 键值
	 */
	public void add(String comment, String key, String value) {
		if (comment != null) {
			content.add('#' + comment);
		}
		if (!content.contains(key)) {
			content.add(key);
		}
		paramemters.put(key, value);
		updateFlag = true;
	}

	/**
	 * 取得属性
	 * @param key 键名
	 * @return 键值
	 */
	public String get(String key) {
		String str = paramemters.get(key);
		// 如果自身配置文件没有找到属性，而且父配置文件存在，则从父配置文件中找
		if (str == null) {
			return parent != null ? parent.get(key) : null;
		} else {
			return str.trim();
		}
	}

	/**
	 * 获取某个开关量
	 * 0：关闭；1：开启
	 * @param key 主键
	 * @return 属性值
	 */
	public boolean isOn(String key) {
		String str = this.get(key);
		return str == null ? false : str.equals("1");
	}

	/**
	 * 删除属性
	 * @param key 主键
	 */
	public void remove(String key) {
		paramemters.remove(key);
		content.remove(key);
		updateFlag = true;
	}

	/**
	 * 返回所有键值
	 *  @return 所有键值
	 */
	public Map<String, String> getAll() {
		return paramemters;
	}
}
